home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / MOUSPP30.ARJ / MOUSE.CPP < prev    next >
C/C++ Source or Header  |  1992-02-21  |  11KB  |  462 lines

  1. /* -------------------------------------------------------------------- */
  2. /* Mouse++ Version 3.0            mouse.cpp            Revised 02/21/92 */
  3. /*                                                                      */
  4. /* General mouse class for Turbo C++/Borland C++.                       */
  5. /* Copyright 1991, 1992 by Carl W. Moreland                             */
  6. /* This source code may be freely distributed as long as the copyright  */
  7. /* notice remains intact.                                               */
  8. /* -------------------------------------------------------------------- */
  9.  
  10. #include <dos.h>
  11. #include "mouse.h"
  12.  
  13. union  REGS  reg;
  14. struct SREGS sreg;
  15.  
  16. Mouse  mouse;
  17. struct time t;
  18.  
  19. unsigned char Mouse::exists  = 0;
  20. unsigned char Mouse::enabled = 0;
  21. unsigned char Mouse::visible = 0;
  22. unsigned char Mouse::buttons = 0;
  23. unsigned char Mouse::button  = 0;
  24. int           Mouse::x       = 0;
  25. int           Mouse::y       = 0;
  26. int           Mouse::xcount  = 0;
  27. int           Mouse::ycount  = 0;
  28. unsigned char Mouse::hotx    = 0;
  29. unsigned char Mouse::hoty    = 0;
  30. int           Mouse::oldeventmask = 0;
  31. int           Mouse::oldeventseg  = 0;
  32. int           Mouse::oldeventoff  = 0;
  33. unsigned      Mouse::clickThreshold = 250;
  34. unsigned char Mouse::handlerInstalled = 0;
  35. unsigned char Mouse::HeadPtr = 0;
  36. unsigned char Mouse::TailPtr = 0;
  37. unsigned char Mouse::event = 0x00;
  38.  
  39. /* -------------------------------------------------------------------- */
  40.  
  41. Mouse::Mouse(void)            // reset mouse - constructor
  42. {
  43.   int found;
  44.  
  45.   _AX = 0x00;
  46.   geninterrupt(0x33);
  47.   found   = _AX;
  48.   buttons = _BX;
  49.   visible = 0;
  50.  
  51.   if(found)
  52.     exists = 1;
  53.   if(!exists) return;
  54.  
  55.   _ES = 0;
  56.   _DX = 0;
  57.   _CX = 0;                // clear the event handler
  58.   _AX = 0x14;
  59.   geninterrupt(0x33);
  60.   oldeventmask = _CX;            // save the old event handler
  61.   oldeventoff  = _DX;
  62.   oldeventseg  = _ES;
  63.  
  64.   _AX = 0x24;                // get the mouse info
  65.   geninterrupt(0x33);
  66.   Info.majorvers = _BH;
  67.   Info.minorvers = _BL;
  68.   Info.type      = _CH;
  69.   Info.irq       = _CL;
  70. }
  71.  
  72. Mouse::~Mouse(void)            // restore mouse - destructor
  73. {
  74.   if(!exists) return;
  75.   _AX = 0x00;                // reset mouse
  76.   geninterrupt(0x33);
  77.  
  78.   if(oldeventmask)            // restore old event handler
  79.   {
  80.     _ES = oldeventseg;
  81.     _DX = oldeventoff;
  82.     _CX = oldeventmask;
  83.     _AX = 0x14;
  84.     geninterrupt(0x33);
  85.   }
  86. }
  87.  
  88. void Mouse::Enable(void)        // enable the mouse
  89. {
  90.   if(!exists || enabled) return;
  91.  
  92.   if(eventMask && !handlerInstalled)    // re-install event handler
  93.   {
  94.     InstallHandler(eventMask, eventHandler);
  95.     handlerInstalled = 1;
  96.   }
  97.   enabled = 1;
  98. }
  99.  
  100. void Mouse::Disable(void)        // disable the mouse
  101. {
  102.   if(!exists || !enabled) return;
  103.  
  104.   if(handlerInstalled)
  105.   {
  106.     ClearHandler();            // disable the event handler
  107.     ClearClick(LEFTBUTTON);
  108.     ClearClick(RIGHTBUTTON);            // clear the multi-click buffers
  109.     ClearClick(CENTERBUTTON);
  110.   }
  111.   Hide();                // turn the cursor off
  112.   enabled = 0;
  113. }
  114.  
  115. void Mouse::Show()                // show mouse cursor
  116. {
  117.   if(!exists || !enabled) return;
  118.   _AX = 0x01;
  119.   geninterrupt(0x33);
  120.   if(visible < 1) visible++;            // visible should now be 1
  121. }
  122.  
  123. void Mouse::Hide(void)            // hide mouse cursor
  124. {
  125.   if(!exists || !enabled) return;
  126.   if(visible < 1) return;
  127.   _AX = 0x02;
  128.   geninterrupt(0x33);
  129.   visible--;                // visible should now be 0
  130. }
  131.  
  132. void Mouse::Move(int x, int y)        // move cursor to col, row
  133. {                    // col & row are pixel coordinates
  134.   if(!exists || !enabled) return;
  135.   _DX = y;
  136.   _CX = x;
  137.   _AX = 0x04;
  138.   geninterrupt(0x33);
  139. }
  140.  
  141. void Mouse::xLimit(int min, int max)    // set min/max column range
  142. {                    // min & max are pixel coordinates
  143.   if(!exists) return;
  144.   _DX = max;
  145.   _CX = min;
  146.   _AX = 0x07;
  147.   geninterrupt(0x33);
  148. }
  149.  
  150. void Mouse::yLimit(int min, int max)    // set min/max row range
  151. {                    // min & max are pixel coordinates
  152.   if(!exists) return;
  153.   _DX = max;
  154.   _CX = min;
  155.   _AX = 0x08;
  156.   geninterrupt(0x33);
  157. }
  158.  
  159. void Mouse::MickToPix(int horiz, int vert)
  160. {                             // set the mickey to pixel ratio
  161.   if(!exists) return;
  162.   _DX = vert;
  163.   _CX = horiz;
  164.   _AX = 0x0F;
  165.   geninterrupt(0x33);
  166. }
  167.  
  168. void Mouse::SetSpeedThreshold(unsigned speed)
  169. {                    // set speed change threshold
  170.   if(!exists) return;
  171.   _DX = speed;
  172.   _AX = 0x13;
  173.   geninterrupt(0x33);
  174. }
  175.  
  176. void Mouse::SetGraphicsCursor(GraphicsCursor& cursor)
  177. {                    // change the graphics cursor
  178.   if(!exists) return;
  179.   _ES = FP_SEG(cursor.image);
  180.   _DX = FP_OFF(cursor.image);
  181.   _CX = cursor.hoty;
  182.   _BX = cursor.hotx;
  183.   _AX = 0x09;
  184.   geninterrupt(0x33);
  185.   hotx = cursor.hotx;
  186.   hoty = cursor.hoty;
  187. }
  188.  
  189. void Mouse::SetTextCursor(TextCursor& cursor)
  190. {                    // change the text cursor
  191.   if(!exists) return;
  192.   _DX = cursor.arg2;
  193.   _CX = cursor.arg1;
  194.   _BX = cursor.type;
  195.   _AX = 0x0A;
  196.   geninterrupt(0x33);
  197.   hotx = 0;
  198.   hoty = 0;
  199. }
  200.  
  201. void Mouse::Position(void)        // update cursor position &
  202. {                    // button status
  203.   if(!exists || !enabled) return;
  204.   _AX = 0x03;
  205.   geninterrupt(0x33);
  206.   button = _BX;
  207.   x = _CX;
  208.   y = _DX;
  209. }
  210.  
  211. int Mouse::Pressed(int mbutton)        // check press status of button
  212. {
  213.   if(!exists || !enabled) return(0);
  214.  
  215.   if(handlerInstalled)
  216.   {
  217.     if(mbutton == LEFTBUTTON)
  218.       return(event & LB_PRESSED);
  219.     else if(mbutton == RIGHTBUTTON)
  220.       return(event & RB_PRESSED);
  221.     else if(mbutton == CENTERBUTTON)
  222.       return(event & CB_PRESSED);
  223.   }
  224.  
  225.   _BX = mbutton;
  226.   _AX = 0x05;
  227.   geninterrupt(0x33);
  228.   button = _AX;
  229.   int BX = _BX;
  230.   if(BX)
  231.   {
  232.     x = _CX;
  233.     y = _DX;
  234.   }
  235.   return(BX);
  236. }
  237.  
  238. int Mouse::Released(int mbutton)    // check release status of button
  239. {
  240.   if(!exists || !enabled) return(0);
  241.  
  242.   if(handlerInstalled)
  243.   {
  244.     if(mbutton == LEFTBUTTON)
  245.       return(event & LB_RELEASED);
  246.     else if(mbutton == RIGHTBUTTON)
  247.       return(event & RB_RELEASED);
  248.     else if(mbutton == CENTERBUTTON)
  249.       return(event & CB_RELEASED);
  250.   }
  251.  
  252.   _AX = 0x06;
  253.   _BX = mbutton;
  254.   geninterrupt(0x33);
  255.   button = _AX;
  256.   int BX = _BX;
  257.   if(BX)
  258.   {
  259.     x = _CX;
  260.     y = _DX;
  261.   }
  262.   return(BX);
  263. }
  264.  
  265. void Mouse::Motion(void)        // get # of mickeys moved
  266. {
  267.   if(!exists || !enabled) return;
  268.   _AX = 0x0B;
  269.   geninterrupt(0x33);
  270.   xcount = _CX;
  271.   ycount = _DX;
  272. }
  273.  
  274. int Mouse::InBox(int left, int top, int right, int bottom)
  275. {                    // see if mouse is in a box
  276.   if(!exists || !enabled) return(0);
  277.  
  278.   if((x>=left) && (y>=top) && (x<=right) && (y<=bottom))
  279.     return(1);
  280.   return(0);
  281. }
  282.  
  283. void Mouse::Exclude(int left, int top, int right, int bottom)
  284. {                    // set up exclusion area
  285.   if(!exists || !enabled) return;
  286.  
  287.   if((x >= (left-15+hotx)) && (y >= (top-15+hoty)) &&
  288.      (x <= (right+hotx)) && (y <= (bottom+hoty)))
  289.     Hide();
  290.   else
  291.     Show();
  292. }
  293.  
  294. void Mouse::SetClickThreshold(unsigned time)
  295. {
  296.   clickThreshold = time;        // time is in milliseconds
  297. }
  298.  
  299. int Mouse::MultiClick(int mbutton)    // check for multiple clicks
  300. {
  301.   if(!exists || !enabled) return(0);
  302.  
  303.   return Click[mbutton].count;
  304. }
  305.  
  306. int Mouse::DoubleClick(int mbutton)     // check for double clicks
  307. {
  308.   if(!exists || !enabled) return(0);
  309.  
  310.   return (Click[mbutton].count == 2);
  311. }
  312.  
  313. void Mouse::ClearClick(int mbutton)    // clear the MultiClick buffer
  314. {
  315.   if(!exists || !enabled) return;
  316.  
  317.   Click[mbutton].count = 0;
  318. }
  319.  
  320. /* ----- Event Driver routines ---------------------------------------- */
  321.  
  322. void Mouse::InstallHandler(unsigned mask, void interrupt (*handler)(void))
  323. {
  324.   if(!exists) return;            // set up an event handler
  325.  
  326.   _ES = FP_SEG(handler);
  327.   _DX = FP_OFF(handler);
  328.   _CX = mask;
  329.   _AX = 0x14;
  330.   geninterrupt(0x33);
  331.  
  332.   handlerInstalled = 1;
  333.   HeadPtr = 0;
  334.   TailPtr = 0;
  335.   eventMask = mask;
  336.   eventHandler = handler;
  337. }
  338.  
  339. void Mouse::ClearHandler(void)        // clear the event handler
  340. {
  341.   if(!exists) return;
  342.  
  343.   _ES = 0;
  344.   _DX = 0;
  345.   _CX = 0;
  346.   _AX = 0x14;
  347.   geninterrupt(0x33);
  348.  
  349.   handlerInstalled = 0;
  350.   HeadPtr = 0;
  351.   TailPtr = 0;
  352. }
  353.  
  354. /* Mouse::Save - stuff the event info in the event buffer */
  355.  
  356. void Mouse::Save(int event, int button, int x, int y, int xcount, int ycount)
  357. {
  358.   unsigned char keymask;
  359.   long time;
  360.  
  361.   if((HeadPtr == TailPtr-1) ||        // see if the buffer is full
  362.      (HeadPtr == MOUSE_BUFFER_SIZE-1 && TailPtr == 0))
  363.     return;
  364.  
  365.   if((event & LB_PRESSED) || (event & RB_PRESSED) || (event & CB_PRESSED))
  366.   {
  367.     gettime(&t);            // get the event time
  368.     time = (long)t.ti_hour*3600000L +    // convert to milliseconds
  369.            (long)t.ti_min*60000L +
  370.            (long)t.ti_sec*1000L +
  371.        (long)t.ti_hund*10L;
  372.  
  373.     _AH = 0x02;
  374.     geninterrupt(0x16);            // get the keyshift mask
  375.     keymask = _AL;
  376.  
  377.     button += keymask << 4;        // add it to the button mask
  378.     if(keymask & 0x03)
  379.       button += 0x08;
  380.   }
  381.   else
  382.     time = 0;                // no button press so time not needed
  383.  
  384.   Buffer[HeadPtr].event  = event;    // store the info in the event buffer
  385.   Buffer[HeadPtr].button = button;
  386.   Buffer[HeadPtr].x      = x;
  387.   Buffer[HeadPtr].y      = y;
  388.   Buffer[HeadPtr].xcount = xcount;
  389.   Buffer[HeadPtr].ycount = ycount;
  390.   Buffer[HeadPtr].time   = time;
  391.  
  392.   if(++HeadPtr >= MOUSE_BUFFER_SIZE)    // increment the head ptr
  393.     HeadPtr = 0;
  394. }
  395.  
  396. void interrupt MouseHandler(void)    // default event handler
  397. {
  398.   mouse.Save(_AX,_BX,_CX,_DX,_DI,_SI);  // save the normal stuff
  399.   EventExit();                              // required for interrupt function
  400. }
  401.  
  402. /* Mouse::GetEvent - read the event buffer and put info into the class */
  403.  
  404. void Mouse::GetEvent(void)
  405. {
  406.   if(!exists || !enabled) return;
  407.  
  408.   int mbutton;
  409.  
  410.   if(HeadPtr != TailPtr)
  411.   {
  412.     event  = Buffer[TailPtr].event;
  413.     button = Buffer[TailPtr].button;
  414.     x      = Buffer[TailPtr].x;
  415.     y      = Buffer[TailPtr].y;
  416.     xcount = Buffer[TailPtr].xcount;
  417.     ycount = Buffer[TailPtr].ycount;
  418.  
  419.     if(Buffer[TailPtr].time)            // store info for MultiClick()
  420.     {
  421.       if(event & LB_PRESSED)
  422.         mbutton = LEFTBUTTON;
  423.       else if(event & RB_PRESSED)
  424.         mbutton = RIGHTBUTTON;
  425.       else if(event & CB_PRESSED)
  426.         mbutton = CENTERBUTTON;
  427.  
  428.       if((Buffer[TailPtr].time - Click[mbutton].time) < clickThreshold)
  429.         Click[mbutton].count++;
  430.       else
  431.         Click[mbutton].count = 1;
  432.  
  433.       Click[mbutton].time = Buffer[TailPtr].time;
  434.     }
  435.  
  436.     if(++TailPtr >= MOUSE_BUFFER_SIZE)
  437.       TailPtr = 0;
  438.   }
  439.   else
  440.   {
  441.     event  = 0;
  442.     xcount = 0;
  443.     ycount = 0;
  444.   }
  445. }
  446.  
  447. void Mouse::ClearEvent(void)        // clear the current event
  448. {
  449.   event  = 0;
  450.   button = 0;
  451.   x      = 0;
  452.   y      = 0;
  453.   xcount = 0;
  454.   ycount = 0;
  455. }
  456.  
  457. void Mouse::ClearBuffer(void)        // clear the event buffer
  458. {
  459.   HeadPtr = 0;
  460.   TailPtr = 0;
  461. }
  462.